#include "AnaDef.h"
#include "AnaAliDef.h"
#include "XGLUtils.h"

#include "AnadEdxFit.h"

void dofit(AnadEdxFit *df)
{
  if(df->GetEntries()<300){
    printf("dofit n<300, not fit! %d\n", df->GetEntries());
    return;
  }

  df->Fit();
}

void loopfit(const Int_t nh, const TString hname[], const TString tag, const TString opt,  const Int_t hid, const TString *types=0x0, const Double_t *ps=0x0)
{
  TH1 *hh = 0x0;

  Int_t istart=0;
  Int_t istop=nh-1;
  if(hid!=-999){
    if(hid>=istart && hid<=istop){
      istart = istop = hid;
    }
    else{
      printf("hid error!! %d %d %d\n", hid, istart, istop);
      exit(1);
    }
  }
    
  for(Int_t ii=istart; ii<=istop; ii++){
    printf("=========== fitting hist: %d/%d %s\n", ii, nh, hname[ii].Data());
      
    gDirectory->GetObject(hname[ii], hh);
    if(!hh){
      printf("no hist! %d %s\n", ii, hname[ii].Data());
      gDirectory->ls();
      exit(1);
    }

    Double_t mom=-999, lowerr=-999, higherr=-999;
    TString ptype="X";
    if(types)
      ptype = types[ii];

    if(ps)
      mom = ps[ii];
    else {
      TString pnum = hh->GetTitle();
      pnum = pnum( pnum.First("=")+1, pnum.Length());
      sscanf(pnum.Data(),"%lf", &mom);
      pnum = pnum( pnum.First("/")+1, pnum.Length());
      pnum = pnum( pnum.First(" ")+1, pnum.Length());
      sscanf(pnum.Data(),"%lf %lf", &lowerr, &higherr);
      printf("xcheck %f %f %f\n", mom, lowerr, higherr);
    }

    AnadEdxFit dfit(ptype, mom, lowerr, higherr);
    dfit.InputData(tag, hh);

    dofit(&dfit);
  }
}

int main(int argc, char *argv[])
{
  gErrorIgnoreLevel = 1001;
  for(Int_t ii=0; ii<argc; ii++){
    printf("%d: %s\n", ii, argv[ii]);
  }

  TString fname(argv[1]);
  TFile * file = new TFile(fname);
  if(!file){
    printf("file not open!! %s\n", fname.Data());
    return 1;
  }

  //dummy
  TString opt;

  Int_t hid=-999;
  if(argc>2){
    hid=atoi(argv[2]);
    printf("==========> hid: %d\n", hid);
  }

  if(fname.Contains("inv8-p")){
    const TString hname[]={"h101", "h102", "h103", "h104", "h105", "h106", "h107", "h201", "h202", "h203", "h204", "h205", "h206", "h207"};
    const TString ptype[]={"PI", "PI", "PI", "PI", "PI", "PI", "PI", "E", "E", "E", "E", "E", "E", "E"};
    const Double_t mom[]={1, 1.5, 2, 3, 4, 5, 6, 1, 1.5, 2, 3, 4, 5, 6};

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "IONTR", opt, hid, ptype, mom);
  }
  else if(fname.Contains("dedx-p.root")){
    const TString hname[]={"h101", "h102", "h103", "h104", "h105", "h106", "h107", "h201", "h202", "h203", "h204", "h205", "h206", "h207"};
    const TString ptype[]={"PI", "PI", "PI", "PI", "PI", "PI", "PI", "E", "E", "E", "E", "E", "E", "E"};
    const Double_t mom[]={1, 1.5, 2, 3, 4, 5, 6, 1, 1.5, 2, 3, 4, 5, 6};

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "pureION", opt, hid, ptype, mom);
  }
  else if(fname.Contains("dEdx_2004_inv8.root")){
    const TString hname[]={"h101", "h102", "h103", "h104", "h105", "h106", "h107", "h108", "h109", "h110", "h111", 
                            "h201", "h202", "h203", "h204", "h205", "h206", "h207", "h208", "h209", "h210", "h211"}; 
    const TString ptype[]={"PI", "PI", "PI", "PI", "PI", "PI", "PI", "PI", "PI", "PI", "PI",
                            "E",  "E",  "E",  "E",  "E",  "E",  "E",  "E",  "E",  "E",  "E"};
    const Double_t mom[]={1, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                          1, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "SPSIONTR", opt, hid, ptype, mom);
  }
  else if(fname.Contains("dEdx_2004_norad.root")){
    const TString hname[]={"h101", "h102", "h103", "h104", "h105", "h106", 
                           "h201", "h202", "h203", "h204", "h205", "h206"};
    const TString ptype[]={"PI", "PI", "PI", "PI", "PI", "PI",
                            "E",  "E",  "E",  "E",  "E",  "E"};
    const Double_t mom[]={1, 2, 4, 6, 8, 10, 
                          1, 2, 4, 6, 8, 10};
    
    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "SPSpureION", opt, hid, ptype, mom);
  }
  else if(fname.Contains("5kGIN")){
    const TString hname[]={
      "h100", "h101", "h102", "h103", "h104", "h105", "h106", "h107", "h108", "h109", "h110", "h111", "h112", "h113", "h114", "h115", "h116", "h117", "h118", "h119", "h120", "h121", "h122", "h123", "h124", "h125", "h126", "h127", "h128", "h129", "h130", "h131", "h132", "h133", "h134", "h135", "h136", "h137", "h138", "h139", "h140", "h141", "h142", "h143", "h144", "h145", "h146", "h147", "h148", "h149"
    };

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "Cosmic5kGIN", opt, hid);    
  }
  else if(fname.Contains("5kGOUT")){
    const TString hname[]={
      "h200", "h201", "h202", "h203", "h204", "h205", "h206", "h207", "h208", "h209", "h210", "h211", "h212", "h213", "h214", "h215", "h216", "h217", "h218", "h219", "h220", "h221", "h222", "h223", "h224", "h225", "h226", "h227", "h228", "h229", "h230", "h231", "h232", "h233", "h234", "h235", "h236", "h237", "h238", "h239", "h240", "h241", "h242", "h243", "h244", "h245", "h246", "h247", "h248", "h249"
    };

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "Cosmic5kGOUT", opt, hid);    
  }
  else if(fname.Contains("5kGoldOUT")){
    const TString hname[]={
      "h200", "h201", "h202", "h203", "h204", "h205", "h206", "h207", "h208", "h209", "h210", "h211", "h212", "h213", "h214", "h215", "h216", "h217", "h218", "h219", "h220", "h221", "h222", "h223", "h224", "h225", "h226", "h227", "h228", "h229", "h230", "h231", "h232", "h233", "h234", "h235", "h236", "h237", "h238", "h239", "h240", "h241", "h242", "h243", "h244", "h245", "h246", "h247", "h248", "h249"
    };

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "Cosmic5kGoldOUT", opt, hid);    
  }
  else if(fname.Contains("1kGIN")){
    const TString hname[]={
      "h100", "h101", "h102", "h103", "h104", "h105", "h106", "h107", "h108", "h109", "h110", "h111", "h112", "h113", "h114", "h115", "h116", "h117", "h118", "h119", "h120", "h121", "h122", "h123", "h124", "h125", "h126", "h127", "h128", "h129", "h130", "h131", "h132", "h133", "h134", "h135", "h136", "h137", "h138", "h139", "h140", "h141", "h142", "h143", "h144", "h145", "h146", "h147", "h148", "h149"
    };

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "Cosmic1kGIN", opt, hid);    
  }
  else if(fname.Contains("1kGOUT")){
    const TString hname[]={
      "h200", "h201", "h202", "h203", "h204", "h205", "h206", "h207", "h208", "h209", "h210", "h211", "h212", "h213", "h214", "h215", "h216", "h217", "h218", "h219", "h220", "h221", "h222", "h223", "h224", "h225", "h226", "h227", "h228", "h229", "h230", "h231", "h232", "h233", "h234", "h235", "h236", "h237", "h238", "h239", "h240", "h241", "h242", "h243", "h244", "h245", "h246", "h247", "h248", "h249"
    };

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "Cosmic1kGOUT", opt, hid);    
  }
  else if(fname.Contains("MC")){//can not use "TRD", mixed with "TR" in AnadEdxFit::SetHist
    const TString hname[]={
      "hh001", "hh002", "hh003", "hh004", "hh005", "hh006", "hh007", "hh008", "hh009", "hh010", "hh011", "hh012", "hh013", "hh014", "hh015", "hh016", "hh017", "hh018", "hh019", "hh020", "hh021", "hh022", "hh023", "hh024", "hh025", "hh026", "hh027", "hh028", "hh029", "hh030", "hh031", "hh032", "hh033", "hh034", "hh035", "hh036", "hh037", "hh038", "hh039", "hh040", "hh041", "hh042", "hh043", "hh044", "hh045", "hh046", "hh047", "hh048", "hh049", "hh050", "hh051", "hh052", "hh053", "hh054", "hh055", "hh056", "hh057", "hh058", "hh059", "hh060", "hh061", "hh062", "hh063", "hh064", "hh065", "hh066", "hh067", "hh068", "hh069", "hh070", "hh071", "hh072", "hh073", "hh074", "hh075", "hh076", "hh077", "hh078", "hh079", "hh080", "hh081", "hh082", "hh083", "hh084", "hh085", "hh086", "hh087", "hh088", "hh089", "hh090", "hh091", "hh092", "hh093", "hh094", "hh095", "hh096", "hh097", "hh098", "hh099", "hh100", "hh101", "hh102", "hh103", "hh104", "hh105", "hh106", "hh107", "hh108", "hh109", "hh110", "hh111"
    };
    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "hMC", opt, hid); 
  }
  else if(fname.Contains("pp")){
    const TString hname[]={
      "h100", "h101", "h102", "h103", "h104", "h105", "h106", "h107", "h108", "h109", "h110", "h111", "h112", "h113", "h114", "h115", "h116", "h117", "h118", "h119", "h120", "h121", "h122", "h123", "h124", "h125", "h126", "h127", "h128", "h129", "h130", "h131", "h132", "h133", "h134", "h135", "h136", "h137", "h138", "h139", "h140", "h141", "h142", "h143", "h144", "h145", "h146", "h147", "h148", "h149", "h150", "h151", "h152", "h153", "h154", "h155", "h156", "h157", "h158", "h159", "h160", "h161"
    };

    const Int_t nh = sizeof(hname)/sizeof(TString);

    loopfit(nh, hname, "pp", opt, hid);
  }
  else {
    printf("no matching fname!! %s\n", fname.Data());
    exit(1);
  }

  file->Close();
  delete file;

  printf("dEdxFit done!!\n");
  return 0;
}
